// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: Implementation of CXFormsElementCase.
//   $Id$

#include "stdafx.h"
#include "caseui.h"
#include "parseCase.h"
#include "XFormsXFormsElement.h"
#include "case.h"
#include "tags.h"
#include "WaitWithMessageLoop.h"


const CComBSTR *  const CXFormsElementCase::sm_asEventNames[] 
= 
{
	&EVENT_SELECTED,
	&EVENT_DESELECTED
};
CXFormsElementCase::CXFormsElementCase(void)
:m_bDeferredContentLoading(true)
,m_bContentLoaded(false)
,m_bParseDone(false)
{
}

CXFormsElementCase::~CXFormsElementCase(void)
{
}

HRESULT CXFormsElementCase::put_XPathExpression(const BSTR bsXPath)
{
	return S_OK;
}

CImpl* CXFormsElementCase::CreateImpl()
{
	CImpl* pFormControl = (CImpl*) new CImplCase(this);

	return pFormControl;
}

CXFormsParse* CXFormsElementCase::CreateParse(CImpl* pImpl)
{
	CXFormsParse* pParse = new CXFormsParseCase((CImplCase*) pImpl);

	return pParse;
}

bool  CXFormsElementCase::ToggleCaseByRemovingContent() const
{
	return false;
}

HRESULT CXFormsElementCase::ConcealCaretIfWithinCurrentCase()
{
	return ConcealCaretIfWithinSelf();
}

HRESULT XFormsCaseInnerLoadContent(VOID ** ppArg)
{
	HRESULT hr = E_INVALIDARG;
	CXFormsElementCase * pCase = reinterpret_cast<CXFormsElementCase*>(ppArg);
	if(pCase)
	{
		CComQIPtr<IHTMLElement> pEl;
		hr = pCase->GetMasterElement(&pEl);
		if(pEl && pCase->m_pFormControl)
		{
			hr = pEl->put_innerHTML(pCase->m_pFormControl->m_sContent);
			pCase->m_bContentLoaded = true;
		}
	}
	return hr;
}


#ifdef CASE_TOGGLES_BYREMOVING_ALL_CONTENT

HRESULT CXFormsElementCase::LoadContent()
{
	HRESULT hr = S_FALSE;
	if(!m_bContentLoaded)
	{
		const UINT msg_DoPutCaseContent = WM_APP + 63;
		xport::PerformOperationWithMessagePump(msg_DoPutCaseContent,XFormsCaseInnerLoadContent,reinterpret_cast<void**>(this));
	}
	return hr;
}

HRESULT CXFormsElementCase::UnloadContent()
{
	CComQIPtr<IHTMLElement> pEl;
	HRESULT hr = GetMasterElement(&pEl);
	if(pEl)
	{
		hr = pEl->put_innerHTML(0);
		m_bContentLoaded = false;
	}
	return hr;
}

HRESULT CXFormsElementCase::SelectedEffect()
{
	if(ToggleCaseByRemovingContent() || (m_bDeferredContentLoading && !m_bContentLoaded))
	{
		LoadContent();
	}
	
	return __super::SelectedEffect();
}



HRESULT CXFormsElementCase::DeselectedEffect()
{
	HRESULT hr = ConcealCaretIfWithinCurrentCase();
	//Don't really care about the return value from above, just exposing it for diagnostic reasons.
	hr = __super::DeselectedEffect();

	if(ToggleCaseByRemovingContent())
	{
		hr = UnloadContent();
	}


	return hr;
}
#endif

STDMETHODIMP CXFormsElementCase::loadContent()
{
	return LoadContent();
}

STDMETHODIMP CXFormsElementCase::unloadContent()
{
	return UnloadContent();
}

STDMETHODIMP CXFormsElementCase::toggle()
{
	return E_NOTIMPL;
}


HRESULT CXFormsElementCase::put_value(BSTR sValue)
{
	// Show and hide the case code should be added here....

	return S_OK;
}

HRESULT CXFormsElementCase::render()
{
	m_bParseDone = true;
	return S_OK;
}

void CXFormsElementCase::populateEvents(void)
{
}

bool CXFormsElementCase::IsAppearanceFull()
{
	bool bReturn = false;
	CComPtr<IHTMLElement> pEl;
	GetMasterElement(&pEl);
	if(pEl)
	{
		CComVariant vtVal;
		pEl->getAttribute(ATTR_APPEAR,1,&vtVal);
		if(vtVal.vt == VT_BSTR && 0 == wcscmp(vtVal.bstrVal,L"full"))
		{
			bReturn = true;
		}
		else
		{
			//See if the parent switch is determined to be appearance="full"
			CComPtr<IHTMLElement> pParent;
			pEl->get_parentElement(&pParent);
			if(pParent)
			{
				CComVariant vtParentVal;
				pParent->getAttribute(ATTR_APPEAR,1,&vtParentVal);
				if(vtParentVal.vt == VT_BSTR && 0 == wcscmp(vtParentVal.bstrVal,L"full"))
				{
					bReturn = true;
				}
			}
		}
	}
	return bReturn;
}

HRESULT CXFormsElementCase::InitBehaviour(void)
{
	RegisterCustomEvents(sm_asEventNames,CXFORMSELEMENTCASE_EVENTS_LENGTH,m_alEventCookies);
	HRESULT hr =  __super::InitBehaviour();

	if(IsAppearanceFull())
	{
		RegisterFindBehaviourAcceptance();
		m_bContentLoaded = true;
	}

	CComPtr<IHTMLElement> pMaster;
	GetMasterElement(&pMaster);
	if(pMaster)
		pMaster->setAttribute(CComBSTR(L"tabIndex"), CComVariant(-1, VT_I4), 1);

	return hr;
}